package com.taxshare.manager.service;


import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;
import com.alibaba.fastjson.JSONObject;
import com.taxshare.jwt.JwtHelper;
import com.taxshare.jwt.JwtInfo;
import com.taxshare.jwt.JwtVo;
import com.taxshare.manager.entity.UserEntity;
import com.taxshare.manager.entity.UserRoleEntity;
import com.taxshare.manager.mapper.UserMapper;
import com.taxshare.manager.view.vo.LoginReqVO;
import com.taxshare.response.beans.Response;
import com.taxshare.tools.util.HttpClientUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.taxshare.manager.constant.ResultConstant.*;


/**
 * 登陆信息
 */
@Service
@Slf4j
@SuppressWarnings("all")
public class LoginService {

    /**
     * JWT token的过期时间 300分钟
     */
    public static final int ACCESS_TOKEN_TIME = 18000;

    /**
     * JWT refresh的过期时间 600分钟
     */
    public static final int REFRESH_TOKEN_TIME = 36000;

    /**
     * JWT refresh的过期时间 600分钟
     */
    public static final long KEY_REFRESH_TOKEN_TIME = 36000;
    @Autowired
    private UserService userService;

    @Autowired
    private UserMapper userMapper;

    /**
     * 用户密码登陆校验
     */
    public Response verify(LoginReqVO bean, HttpServletResponse response) throws Exception {
        //用户信息
        String userMsg = bean.getUserMsg().trim();
        //用户密码
        String userPwd = bean.getUserPwd();
        UserEntity userEntity = userService.findByUserLoginName(userMsg);
        //账号不存在
        if (userEntity == null) {
            return Response.warn(RET_MAN_40010_CODE, RET_MAN_40010_MSG);
        }
        //获取密文密码
        String pwd = userEntity.getUserPassword();
        //验证密码
        if (!userPwd.equals(pwd)) {
            return Response.warn(RET_MAN_40011_CODE, RET_MAN_40011_MSG);
        }
        //用户ID
        String userId = userEntity.getUserId();
        UserRoleEntity roleEntity = userService.findRoleByUserId(userId);
        if (roleEntity == null) {
            return Response.warn(RET_MAN_40014_CODE, RET_MAN_40014_MSG);
        }
        //验证通过后,生成JWT
        Map<String, Object> userMap = new HashMap<>();
        userMap.put("userId", userEntity.getUserId());
        userMap.put("userLoginName", userEntity.getUserLoginName());
        userMap.put("userNickName", userEntity.getUserNickName());
        userMap.put("userType", userEntity.getUserType());
        userMap.put("tenantId", userEntity.getTenantId());
        userMap.put("roleId", roleEntity.getRoleId());
        userMap.put("expandField", new HashMap<>());
        JwtVo token = generateToken(userMap);
        //返回结果对象
        Map<String, Object> returnMap = new HashMap<>(8);
        returnMap.put("token", token);
        returnMap.put("userInfo", userEntity);
        return Response.success(returnMap);
    }

    /**
     * 刷新token
     */
    public Response refresh(String oldToken) throws Exception {
        Map<String, Object> reMap = new HashMap<>(16);
        try {
            //构造Map与登陆信息一致
            JwtInfo info = JwtHelper.getInfoFromToken(oldToken);
            reMap.put("userId", info.getUserId());
            reMap.put("userLoginName", info.getUserLoginName());
            reMap.put("userNickName", info.getUserNickName());
            reMap.put("userType", info.getUserType());
            reMap.put("roleId", info.getRoleId());
            reMap.put("tenantId", info.getTenantId());
            //拓展字段
            reMap.put("expandField", info.getExpandField());
        } catch (Exception e) {
            log.error("解析令牌失败：", e);
            return Response.warn(RET_MAN_40012_CODE, RET_MAN_40012_MSG);
        }
        //重新生成token
        JwtVo vo = generateToken(reMap);
        return Response.success(vo);
    }

    /**
     * 根据用户id获取token
     */
    public Response getToken(String userid) throws Exception {
        Map<String, Object> reMap = new HashMap<>(16);
        try {
            //构造Map与登陆信息一致
            UserEntity userEntity = userMapper.selectById(userid);
            reMap.put("userId", userEntity.getUserId());
            reMap.put("userLoginName", userEntity.getUserLoginName());
            reMap.put("userNickName", userEntity.getUserNickName());
            reMap.put("userType", userEntity.getUserType());
            reMap.put("roleId", "");
            reMap.put("tenantId", userEntity.getTenantId());
            //拓展字段
            reMap.put("expandField", new HashMap<>());
        } catch (Exception e) {
            log.error("解析令牌失败：", e);
            return Response.warn(RET_MAN_40012_CODE, RET_MAN_40012_MSG);
        }
        //重新生成token
        JwtVo vo = generateToken(reMap);
        return Response.success(vo);
    }

    /**
     * 根据用户id获取token
     */
    public Map<String, Object> getToken01(String userLoginName) throws Exception{
        Map<String, Object> resultMap = new HashMap<>();
        Map<String, Object> reMap = new HashMap<>(16);
            //构造Map与登陆信息一致
        UserEntity userEntity = userService.findByUserLoginName(userLoginName);
        if(userEntity!=null) {
            reMap.put("userId", userEntity.getUserId());
            reMap.put("userLoginName", userEntity.getUserLoginName());
            reMap.put("userNickName", userEntity.getUserNickName());
            reMap.put("userType", userEntity.getUserType());
            reMap.put("roleId", "");
            reMap.put("tenantId", userEntity.getTenantId());
            //拓展字段
            reMap.put("expandField", new HashMap<>());
            //重新生成token
            JwtVo vo = generateToken(reMap);
            resultMap.put("code", "0000");
            resultMap.put("userNickName", userEntity.getUserNickName());
            resultMap.put("refreshToken", vo.getRefreshToken());
            resultMap.put("accessToken", vo.getAccessToken());
        }else{
            resultMap.put("code", "0001");
            resultMap.put("msg", "用户不存在");
        }
        return resultMap;
    }

    /**
     * JWT令牌生成
     */
    public JwtVo generateToken(Map<String, Object> map) throws Exception {
        //用户信息对象
        JwtInfo info = new JwtInfo();
        //设置信息
        info.setUserId(String.valueOf(map.get("userId")));
        info.setUserLoginName(String.valueOf(map.get("userLoginName")));
        info.setUserNickName(String.valueOf(map.get("userNickName")));
        info.setUserType(String.valueOf(map.get("userType")));
        info.setTenantId(String.valueOf(map.get("tenantId")));
        info.setRoleId(String.valueOf(map.get("roleId")));
        info.setExpandField((Map<String, Object>) map.get("expandField"));
        String accessToken = JwtHelper.generateToken(info, ACCESS_TOKEN_TIME);
        String refreshToken = JwtHelper.generateToken(info, REFRESH_TOKEN_TIME);
        return new JwtVo(accessToken, refreshToken);
    }

    /**
     * sso登录
     *
     * @param ticket
     * @param uri
     * @return
     */
    public Response ssoLogin(String ticket, String service, String uri) throws Exception {
        String validateUrl = "http://" + uri + "/validate?ticket=" + ticket + "&service=" + service;
        log.error(">>>>>sso validate url:{}", validateUrl);
        String result = HttpClientUtil.sendGet(validateUrl, null);
        log.error(">>>>>sso校验接口返回信息：{}", result);
        if (StrUtil.isNotBlank(result) && result.contains("yes")) {
            String staffCode = result.replace("yes", "").trim();
            //1、查询用户信息
            UserEntity userEntity = userService.findByUserLoginName(staffCode);
            if (userEntity != null) {
                //2、获取角色信息
                String userId = userEntity.getUserId();
                UserRoleEntity roleEntity = userService.findRoleByUserId(userId);
                //3、验证通过后,生成JWT
                Map<String, Object> userMap = new HashMap<>();
                userMap.put("userId", userEntity.getUserId());
                userMap.put("userLoginName", userEntity.getUserLoginName());
                userMap.put("userNickName", userEntity.getUserNickName());
                userMap.put("userType", userEntity.getUserType());
                userMap.put("tenantId", userEntity.getTenantId());
                if (roleEntity != null) {
                    userMap.put("roleId", roleEntity.getRoleId());
                }
                userMap.put("expandField", new HashMap<>());
                JwtVo vo = generateToken(userMap);
                //返回结果对象
                Map<String, Object> returnMap = new HashMap<>(8);
                returnMap.put("token", vo);
                returnMap.put("userInfo", userEntity);
                return Response.success(returnMap);
            } else {
                return Response.error("MANAGER_SSO_002", "用户信息不存在【staffCode:" + staffCode + "】");
            }
        } else {
            return Response.error("MANAGER_SSO_001", "OA单点用户信息校验失败！");
        }
    }

    /**
     * sso登录
     *
     * @param ticket
     * @param uri
     * @return
     */
    public Response ssoCarLogin(String token, String url) throws Exception {
        String validateUrl = url+"?token=" + token;
        log.error(">>>>>sso validate url:{}", validateUrl);
        String result = HttpClientUtil.sendGetHead(validateUrl, null);
        log.error(">>>>>sso校验接口返回信息：{}", result);
        if (StrUtil.isNotBlank(result)) {
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (jsonObject.get("user_info") != null) {
                JSONObject userInfo = JSONObject.parseObject(jsonObject.get("user_info").toString());
                String userName = String.valueOf(userInfo.get("username"));
                //1、查询用户信息
                UserEntity userEntity = userService.findByUserLoginName(userName);
                if (userEntity != null) {
                    //2、获取角色信息
                    String userId = userEntity.getUserId();
                    UserRoleEntity roleEntity = userService.findRoleByUserId(userId);
                    //3、验证通过后,生成JWT
                    Map<String, Object> userMap = new HashMap<>();
                    userMap.put("userId", userEntity.getUserId());
                    userMap.put("userLoginName", userEntity.getUserLoginName());
                    userMap.put("userNickName", userEntity.getUserNickName());
                    userMap.put("userType", userEntity.getUserType());
                    userMap.put("tenantId", userEntity.getTenantId());
                    if (roleEntity != null) {
                        userMap.put("roleId", roleEntity.getRoleId());
                    }
                    userMap.put("expandField", new HashMap<>());
                    JwtVo vo = generateToken(userMap);
                    //返回结果对象
                    Map<String, Object> returnMap = new HashMap<>(8);
                    returnMap.put("token", vo);
                    returnMap.put("userInfo", userEntity);
                    return Response.success(returnMap);
                } else {
                    return Response.error("MANAGER_SSO_002", "用户信息不存在【staffCode:" + userName + "】");
                }
            } else {
                return Response.error("MANAGER_SSO_001", "OA单点用户信息校验失败！");
            }
        } else {
            return Response.error("MANAGER_SSO_001", result);
        }
    }
}